#include "39dll.h"

CList buffers;
CList sockets;
CList files;

//Sockets
int tcpconnect(char* ip, int port, int mode)
{
	CSocket* sock = new CSocket();
	if(sock->tcpconnect(ip, (int)port, (int)mode))
		return AddSocket(sock);
	delete sock;
	return -1;
}

int tcplisten(int port, int max, int mode)
{
	CSocket* sock = new CSocket();
	if(sock->tcplisten((int)port, (int) max,(int)mode))
		return AddSocket(sock);
	delete sock;
	return -1;
}

int tcpaccept(int sockid, int mode)
{
	CSocket*sock = (CSocket*)sockets.item((int)sockid);
	if(sock == NULL)return -1;
	CSocket*sock2 = sock->tcpaccept((int)mode);
	if(sock2 != NULL)return AddSocket(sock2);
	return -1;
}

char* tcpip(int sockid)
{
	CSocket*sock = (CSocket*)sockets.item((int)sockid);
	if(sock == NULL)return NULL;
	return sock->tcpip();
}

int tcpconnected(int sockid)
{
	CSocket*sock = (CSocket*)sockets.item((int)sockid);
	if(sock == NULL)return 0;
	if(sock->tcpconnected())return 1;
	else return 0;
}

int udpconnect(int port, int mode)
{
	CSocket* sock = new CSocket();
	if(sock->udpconnect((int)port, (int)mode))
		return AddSocket(sock);
	delete sock;
	return -1;
}

int sendmessage(int sockid, char*ip, int port, int buffid)
{
	CSocket*sock = (CSocket*)sockets.item((int)sockid);
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(sock == NULL)return -1;
	if(buff == NULL)return -2;
	int size = sock->sendmessage(ip, (int)port, buff);
	if(size < 0)return -sock->lasterror();
	return size;
}

int receivemessage(int sockid, int len, int buffid)
{
	CSocket*sock = (CSocket*)sockets.item((int)sockid);
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(sock == NULL)return -1;
	if(buff == NULL)return -2;
	int size = sock->receivemessage((int)len, buff);
	if(size < 0)
	{
		int error = sock->lasterror();
		if(error == 10054)return 0;
		return -error;
	}
	return size;
}

int peekmessage(int sockid, int len, int buffid)
{
	CSocket*sock = (CSocket*)sockets.item((int)sockid);
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(sock == NULL)return -1;
	if(buff == NULL)return -2;
	int size = sock->peekmessage((int)len, buff);
	if(size < 0)
	{
		int error = sock->lasterror();
		if(error == 10054)return 0;
		return -error;
	}
	return size;
}

int setformat(int sockid, int mode, char*sep)
{
	CSocket*sock = (CSocket*)sockets.item((int)sockid);
	if(sock == NULL)return -1;
	return sock->SetFormat((int)mode, sep);
}

int setsync(int sockid, int mode)
{
	CSocket*sock = (CSocket*)sockets.item((int)sockid);
	if(sock == NULL)return -1;
	sock->setsync((int)mode);
	return 1;
}

int closesock(int sockid)
{
	CSocket*sock = (CSocket*)sockets.item((int)sockid);
	if(sock == NULL)return -1;
	delete sock;
	sockets.set((int)sockid, NULL);
	return 1;
}

int socklasterror(int sockid)
{
	CSocket*sock = (CSocket*)sockets.item((int)sockid);
	if(sock == NULL)return -1;
	return -sock->lasterror();
}

char* myhost()
{
	return CSocket::myhost();
}

int sockexit()
{
	CSocket::SockExit();
	return 1;
}

int sockstart()
{
	CSocket::SockStart();
	return 1;
}

char* hostip(char*host)
{
	return CSocket::GetIp(host);
}

int getsocketid(int sockid)
{
	CSocket*sock = (CSocket*)sockets.item((int)sockid);
	if(sock == NULL)return -1;
	return sock->sockid;
}

//Buffers
int writebyte(unsigned char val, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->writebyte((unsigned char)val);
}

int writeshort(short val, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->writeshort((short)val);
}

int writeushort(unsigned short val, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->writeushort((unsigned short)val);
}

int writeint(int val, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->writeint((int)val);
}

int writeuint(unsigned int val, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->writeuint((unsigned int)val);
}

int writefloat(float val, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->writefloat((float)val);
}

int writedouble(double val, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->writedouble(val);
}

int writechars(char*str, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->writechars(str);
}

int writestring(char*str, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->writestring(str);
}

unsigned char readbyte(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->readbyte();
}

short readshort(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->readshort();
}

unsigned short readushort(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->readushort();
}

int readint(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->readint();
}

unsigned int readuint(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->readuint();
}

float readfloat(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->readfloat();
}

double readdouble(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->readdouble();
}

char* readchars(int len, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return NULL;
	return buff->readchars((int)len);
}

char* readstring(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return NULL;
	return buff->readstring();
}

char* readsep(char*sep, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return NULL;
	return buff->readsep(sep);
}

int getpos(int pos, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	if(pos == 0)return buff->writepos;
	else return buff->readpos;
}

int clearbuffer(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	buff->clear();
	return 1;
}

int buffsize(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->count;
}

int setpos(int pos, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	buff->readpos = (int)pos;
	buff->writepos = (int)pos;
	return pos;
}

int bytesleft(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return buff->bytesleft();
}

int createbuffer()
{
	CBuffer* buff = new CBuffer();
	return AddBuffer(buff);
}

int freebuffer(int buffid)
{
	if(buffid == 0)return 0; //no deleting default buffer
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	delete buff;
	buffers.set((int)buffid, NULL);
	return 1;
}

int copybuffer(int destinationid, int sourceid)
{
	CBuffer*destination = (CBuffer*)buffers.item((int)destinationid);
	if(destination == NULL)return 0;
	CBuffer*source = (CBuffer*)buffers.item((int)sourceid);
	if(source == NULL)return 0;
	destination->addBuffer(source);
	return 1;

}

int copybuffer2(int destinationid, int start, int len, int sourceid)
{
	CBuffer*destination = (CBuffer*)buffers.item((int)destinationid);
	if(destination == NULL)return 0;
	CBuffer*source = (CBuffer*)buffers.item((int)sourceid);
	if(source == NULL)return 0;
	destination->addBuffer(source->data+(int)start, (int)len);
	return 1;

}
//tools
char* getmacaddress()
{
	return CTools::getmacaddress();
}

int bufferencrypt(char*pass, int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	CTools::encryptedbuffer(buff, pass);
	return 1;
}

int adler32(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return CTools::adler32(buff);
}

int bufferexists(int buffid)
{
	CBuffer*buff = (CBuffer*)buffers.item((int)buffid);
	if(buff == NULL)return 0;
	return 1;
}

int netconnected()
{
	return CTools::netconnected();
}

int AddBuffer(CBuffer*b)
{
	for(int i = 0; i < buffers.count; i ++)
	{
		if(buffers[i] == NULL)
		{
			buffers.set(i, b);
			return i;
		}
	}
	buffers.Add(b);
	return buffers.count-1;
}

int AddSocket(CSocket*b)
{
	for(int i = 0; i < sockets.count; i ++)
	{
		if(sockets[i] == NULL)
		{
			sockets.set(i, b);
			return i;
		}
	}
	sockets.Add(b);
	return sockets.count-1;
}

int AddFile(HANDLE b)
{
	for(int i = 0; i < files.count; i ++)
	{
		if(files[i] == NULL)
		{
			files.set(i, b);
			return i;
		}
	}
	files.Add(b);
	return files.count-1;
}

void Init()
{
    CSocket::SockStart();
    buffers.Add(new CBuffer());
    sockets.Add(new CSocket()); //dummy socket
}

void CleanUp()
{
	CSocket::SockExit();
	for(int i = 0; i < buffers.count; i++)
		if(buffers[i] != NULL)
			delete (CBuffer*)buffers.item(i);
	for(int i = 0; i < sockets.count; i++)
		if(sockets[i] != NULL)
			delete (CSocket*)sockets.item(i);
	for(int i = 0; i < files.count; i ++)
		if(files[i] != NULL)
			CTools::BinClose((HANDLE)files.item(i));
}

